package sf.database.listener;

import javax.persistence.PostLoad;
import javax.persistence.PostPersist;
import javax.persistence.PostRemove;
import javax.persistence.PostUpdate;
import javax.persistence.PrePersist;
import javax.persistence.PreRemove;
import javax.persistence.PreUpdate;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

public class EntityListenerContext {
    protected Object entityListener;

    protected Class<?> entityListenerClass;
    /**
     * entityListener 的 class---> Method
     */
    protected Map<Class<?>, Method> map = new HashMap<>();

    /**
     * @param object 实体对象
     * @param clazz
     */
    public void runEntityListener(Object object, Class<?> clazz) {
        if (entityListener == null && entityListenerClass != null) {
            try {
                entityListener = entityListenerClass.getDeclaredConstructor().newInstance();
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
        if (entityListener instanceof EntityListener) {
            EntityListener context = (EntityListener) entityListener;
            if (clazz == PrePersist.class) {
                context.prePersist(object);
            } else if (clazz == PostPersist.class) {
                context.postPersist(object);
            } else if (clazz == PreUpdate.class) {
                context.preUpdate(object);
            } else if (clazz == PostUpdate.class) {
                context.postUpdate(object);
            } else if (clazz == PreRemove.class) {
                context.preRemove(object);
            } else if (clazz == PostRemove.class) {
                context.postRemove(object);
            } else if (clazz == PostLoad.class) {
                context.postLoad(object);
            }
        } else {
            Method method = map.get(clazz);
            if (method != null) {
                try {
                    method.invoke(entityListener, object);
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }

    public Object getEntityListener() {
        return entityListener;
    }

    public void setEntityListener(Object entityListener) {
        this.entityListener = entityListener;
    }

    public Class<?> getEntityListenerClass() {
        return entityListenerClass;
    }

    public void setEntityListenerClass(Class<?> entityListenerClass) {
        this.entityListenerClass = entityListenerClass;
    }
}
